import json

from django.views import View
from django.http import JsonResponse
from rest_framework import status
from rest_framework.generics import GenericAPIView, ListCreateAPIView, RetrieveAPIView, UpdateAPIView, DestroyAPIView, \
    get_object_or_404
from rest_framework.mixins import ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, \
    DestroyModelMixin
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.viewsets import ViewSet, ModelViewSet

from book.models import BookInfo,PeopleInfo
from book.serializers import BookInfoModelSerializer,PeopleInfoModelSerializer


class BookListView(View):
    """
    查询所有图书
    """

    def get(self, request):
        queryset = BookInfo.objects.all()
        book_list = []
        for book in queryset:
            book_list.append({
                'id': book.id,
                'name': book.name,
                'pub_date': book.pub_date
            })
        return JsonResponse(book_list, safe=False)

    def post(self, request):
        json_bytes = request.body
        json_str = json_bytes.decode()
        book_dict = json.loads(json_str)

        book = BookInfo.objects.create(
            name=book_dict.get('name'),
            pub_date=book_dict.get('pub_date')
        )

        return JsonResponse({
            'id': book.id,
            'name': book.name,
            'pub_date': book.pub_date
        }, safe=False)


class BookDetailView(View):
    def get(self, request, pk):
        try:
            book = BookInfo.objects.get(id=pk)
        except BookInfo.DoesNotExist:
            return JsonResponse({}, status=404)

        return JsonResponse({
            'id': book.id,
            'name': book.name,
            'pub_date': book.pub_date
        })

    def put(self, request, pk):
        try:
            book = BookInfo.objects.get(id=pk)
        except BookInfo.DoesNotExist:
            return JsonResponse({}, status=404)

        json_bytes = request.body
        json_str = json_bytes.decode()
        book_dict = json.loads(json_str)

        book.name = book_dict.get('name')
        book.pub_date = book_dict.get('pub_date')
        book.save()
        return JsonResponse({
            'id': book.id,
            'name': book.name,
            'pub_date': book.pub_date
        })

    def delete(self, request, pk):
        try:
            book = BookInfo.objects.get(id=pk)
        except BookInfo.DoesNotExist:
            return JsonResponse({}, status=404)
        book.delete()
        return JsonResponse({}, status=204)


class BookListAPIView(APIView):
    def get(self, request):
        # query_params = request.query_params
        # print(query_params)
        books = BookInfo.objects.all()
        serializer = BookInfoModelSerializer(instance=books, many=True)
        # return JsonResponse({'code': 'get', 'books': serializer.data})
        return Response(serializer.data)

    def post(self, request):
        data = request.data
        serializer = BookInfoModelSerializer(data=data)
        serializer.is_valid()
        serializer.save()
        return Response(serializer.data)


class BookListGenericAPIView(GenericAPIView):
    queryset = BookInfo.objects.all()

    # def get_queryset(self):
    #     return BookInfo.objects.all()
    serializer_class = BookInfoModelSerializer

    # def get_serializer_class(self):
    #     return BookInfoModelSerializer

    def get(self, request):
        # books = BookInfo.objects.all()
        # books = self.queryset
        books = self.get_queryset()

        # serializer = BookInfoModelSerializer(instance=books, many=True)
        # serializer = self.serializer_class(instance=books, many=True)
        serializer = self.get_serializer(instance=books, many=True)

        return Response(serializer.data)

    def post(self, request):
        data = request.data
        serializer = self.get_serializer(data=data)
        serializer.is_valid()
        serializer.save()
        return Response(serializer.data)


class BookListMixinAPIView(ListModelMixin, CreateModelMixin, GenericAPIView):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoModelSerializer

    def get(self, request):
        return self.list(request)

    def post(self, request):
        return self.create(request)


class BookListCreateAPIView(ListCreateAPIView):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoModelSerializer


class BookListDetailAPIView(GenericAPIView):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoModelSerializer

    # lookup_field = 'pk'
    def get(self, request, pk):
        # book = BookInfo.objects.get(id=pk)
        # book = self.queryset.get(id=pk)
        # book = self.get_queryset().get(id=pk)
        book = self.get_object()
        serializer = self.get_serializer(instance=book)
        return Response(serializer.data)

    def put(self, request, pk):
        book = self.get_object()
        data = request.data
        serializer = self.get_serializer(instance=book, data=data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data)

    def delete(self, request, pk):
        book = self.get_object()
        book.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)


class BookListRetrieveModelAPIView(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, GenericAPIView):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoModelSerializer

    def get(self, request, pk):
        return self.retrieve(request)

    def put(self, request, pk):
        return self.update(request)

    def delete(self, request, pk):
        return self.destroy(request)


class BookListRetrieveAPIView(RetrieveAPIView, UpdateAPIView, DestroyAPIView):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoModelSerializer


# 视图集
class BookViewSet(ViewSet):
    def list(self, request):
        queryset = BookInfo.objects.all()
        serialize = BookInfoModelSerializer(instance=queryset, many=True)
        return Response(serialize.data)

    def create(self, request):
        pass

    def retrieve(self, request, pk=None):
        queryset = BookInfo.objects.all()
        user = get_object_or_404(queryset, pk=pk)
        serialize = BookInfoModelSerializer(instance=user)
        return Response(serialize.data)

    def update(self, request, pk=None):
        pass

    def partial_update(self, request, pk=None):
        pass

    def destroy(self, request, pk=None):
        pass

from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import IsAuthenticated
class BookModelViewSet(ModelViewSet):
    authentication_classes = [SessionAuthentication]
    permission_classes=[IsAuthenticated]
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoModelSerializer


class PeploeModelViewSet(ModelViewSet):
    authentication_classes = [SessionAuthentication]
    permission_classes=[IsAuthenticated]
    queryset = PeopleInfo.objects.all()
    serializer_class = PeopleInfoModelSerializer